package com.study.springbootsecurity.config.statemachine;

import jakarta.annotation.Resource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.statemachine.persist.RepositoryStateMachinePersist;
import org.springframework.statemachine.redis.RedisStateMachineContextRepository;
import org.springframework.statemachine.redis.RedisStateMachinePersister;

/**
 * @Description: TODO 二维码状态机持久化配置
 * @author: Huangjianyun
 * @date: 2025-06-21 17:09
 */
@Configuration
public class QrCodePersist<S,E>{

    @Resource
    private RedisConnectionFactory redisConnectionFactory;
    /**
     * 持久化配置，用于将 Spring StateMachine 的上下文信息存储到 Redis。
     * 此配置使得状态机在分布式系统中能够保持状态一致性，因为多个应用实例可以共享同一个 Redis 存储。
     * 这个状态机永久有效 redis默认没有设置有效时间
     * @return 配置好的 RedisStateMachinePersister 实例
     */
    @Bean(name = "qrCodeRedisPersister") // 定义一个 Spring Bean，并为其指定一个唯一的名称
    public RedisStateMachinePersister<E, S> getRedisPersister() {
        // 1. 创建 RedisStateMachineContextRepository
        // 这个 Repository 是 Spring StateMachine 内部用于与 Redis 进行交互，
        // 存储和读取 StateMachineContext 对象的关键组件。
        // 它负责将 StateMachineContext 序列化为字节，并存储到 Redis 中。
        RedisStateMachineContextRepository<E, S> repository = new RedisStateMachineContextRepository<>(redisConnectionFactory);

        // 2. 创建 RepositoryStateMachinePersist
        // 这个类是 StateMachinePersist 接口的一个实现，它使用上面创建的 Repository
        // 来执行实际的 StateMachineContext 的读写操作。
        // 它是 StateMachinePersister 的底层持久化逻辑提供者。
        RepositoryStateMachinePersist p = new RepositoryStateMachinePersist<>(repository);

        // 3. 创建并返回 RedisStateMachinePersister
        // 这是顶层的持久化器，Spring StateMachine 在需要持久化或恢复状态时，会使用这个 Persister。
        // 它封装了底层 StateMachinePersist 的细节，提供更友好的接口。
        // 默认情况下，RedisStateMachinePersister 会将 StateMachineContext 以 Java 序列化的形式存储，
        // 并且如果不手动设置，Key 可能不会有过期时间（TTL）。
        // 注意：如果你需要自定义序列化方式（如JSON）或更精细的TTL控制（如KEEPTTL），
        // 你可能需要一个自定义的 StateMachinePersist 实现，而不是直接使用这个默认的 RedisStateMachinePersister。
        return new RedisStateMachinePersister<>(p);
    }
}
